home *** CD-ROM | disk | FTP | other *** search
/ Chip 2005 August (Alt) / CHIP 2005-08.1.iso / program / guvenlik / syslinux-3.07.exe / highmem.inc < prev    next >
Encoding:
Text File  |  2004-12-17  |  3.9 KB  |  146 lines

  1. ;; $Id: highmem.inc,v 1.4 2004/12/17 06:42:01 hpa Exp $
  2. ;; -----------------------------------------------------------------------
  3. ;;   
  4. ;;   Copyright 1994-2004 H. Peter Anvin - All Rights Reserved
  5. ;;
  6. ;;   This program is free software; you can redistribute it and/or modify
  7. ;;   it under the terms of the GNU General Public License as published by
  8. ;;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
  9. ;;   Boston MA 02111-1307, USA; either version 2 of the License, or
  10. ;;   (at your option) any later version; incorporated herein by reference.
  11. ;;
  12. ;; -----------------------------------------------------------------------
  13.  
  14. ;;
  15. ;; highmem.inc
  16. ;; 
  17. ;; Probe for the size of high memory.  This can be overridden by a
  18. ;; mem= command on the command line while booting a new kernel.
  19. ;;
  20.  
  21.         section .text
  22.  
  23. ;
  24. ; This is set up as a subroutine; it will set up the global variable
  25. ; HighMemSize.  All registers are preserved.  Assumes DS == CS.
  26. ;
  27. highmemsize:
  28.         push es
  29.         pushad
  30.  
  31. ;
  32. ; First, try INT 15:E820 (get BIOS memory map)
  33. ;
  34. get_e820:
  35.         xor ebx,ebx            ; Start with first record
  36.         mov dword [E820Max],-(1 << 20)    ; Max amount of high memory
  37.         mov dword [E820Mem],ebx        ; Detected amount of high memory
  38.         mov es,bx            ; Need ES = DS = 0 for now
  39.         jmp short .do_e820        ; Skip "at end" check first time!
  40. .int_loop:    and ebx,ebx            ; If we're back at beginning...
  41.         jz .e820_done            ; ... we're done
  42. .do_e820:    mov eax,0000E820h
  43.         mov edx,534D4150h        ; "SMAP" backwards
  44.         xor ecx,ecx
  45.         mov cl,20            ; ECX <- 20
  46.         mov di,E820Buf
  47.         int 15h
  48.         jnc .no_carry
  49.         ; If carry, ebx == 0 means error, ebx != 0 means we're done
  50.         and ebx,ebx
  51.         jnz .e820_done
  52.         jmp no_e820
  53. .no_carry:
  54.         cmp eax,534D4150h
  55.         jne no_e820
  56. ;
  57. ; Look for a memory block starting at <= 1 MB and continuing upward
  58. ;
  59.         cmp dword [E820Buf+4], byte 0
  60.         ja .int_loop            ; Start >= 4 GB?
  61.         mov edx, (1 << 20)
  62.         sub edx, [E820Buf]
  63.         jnb .ram_range            ; Start >= 1 MB?
  64.         ; If we get here, it starts > 1 MB but < 4 GB; if this is a
  65.         ; *non*-memory range, remember this as unusable; some BIOSes
  66.         ; get the length of primary RAM wrong!
  67.         cmp dword [E820Buf+16], byte 1
  68.         je .int_loop            ; If it's memory, don't worry about it
  69.         neg edx                ; This means what for memory limit?
  70.         cmp edx,[E820Max]        ; Better or worse
  71.         jnb .int_loop
  72.         mov [E820Max],edx
  73.         jmp .int_loop
  74.         
  75. .ram_range:
  76.         stc
  77.         sbb eax,eax            ; eax <- 0xFFFFFFFF
  78.         cmp dword [E820Buf+12], byte 0
  79.         ja .huge            ; Size >= 4 GB
  80.         mov eax, [E820Buf+8]
  81. .huge:        sub eax, edx            ; Adjust size to start at 1 MB
  82.         jbe .int_loop            ; Completely below 1 MB?
  83.  
  84.         ; Now EAX contains the size of memory 1 MB...up
  85.         cmp dword [E820Buf+16], byte 1
  86.         jne .int_loop            ; High memory isn't usable memory!!!!
  87.  
  88.         ; We're good!
  89.         mov [E820Mem],eax
  90.         jmp .int_loop            ; Still need to add low 1 MB
  91.  
  92. .e820_done:
  93.         mov eax,[E820Mem]
  94.         and eax,eax
  95.         jz no_e820            ; Nothing found by E820?
  96.         cmp eax,[E820Max]        ; Make sure we're not limited
  97.         jna got_highmem_add1mb
  98.         mov eax,[E820Max]
  99.         jmp got_highmem_add1mb
  100.  
  101. ;
  102. ; INT 15:E820 failed.  Try INT 15:E801.
  103. ;
  104. no_e820:
  105.         mov ax,0e801h            ; Query high memory (semi-recent)
  106.         int 15h
  107.         jc no_e801
  108.         cmp ax,3c00h
  109.         ja no_e801            ; > 3C00h something's wrong with this call
  110.         jb e801_hole            ; If memory hole we can only use low part
  111.  
  112.         mov ax,bx
  113.         shl eax,16            ; 64K chunks
  114.         add eax,(16 << 20)        ; Add first 16M
  115.         jmp short got_highmem                
  116.  
  117. ;
  118. ; INT 15:E801 failed.  Try INT 15:88.
  119. ;
  120. no_e801:
  121.         mov ah,88h            ; Query high memory (oldest)
  122.         int 15h
  123.         cmp ax,14*1024            ; Don't trust memory >15M
  124.         jna e801_hole
  125.         mov ax,14*1024
  126. e801_hole:
  127.         and eax,0ffffh
  128.         shl eax,10            ; Convert from kilobytes
  129. got_highmem_add1mb:
  130.         add eax,(1 << 20)        ; First megabyte
  131. got_highmem:
  132. %if HIGHMEM_SLOP != 0
  133.         sub eax,HIGHMEM_SLOP
  134. %endif
  135.         mov [HighMemSize],eax
  136.         popad
  137.         pop es
  138.         ret                ; Done!
  139.  
  140.         section .bss
  141.         alignb 4
  142. E820Buf        resd 5            ; INT 15:E820 data buffer
  143. E820Mem        resd 1            ; Memory detected by E820
  144. E820Max        resd 1            ; Is E820 memory capped?
  145. HighMemSize    resd 1            ; End of memory pointer (bytes)
  146.